Skip to content

lkl: make object_is_on_stack() check host thread stacks - #639

Merged
tavip merged 1 commit into
lkl:masterfrom
clingfei:master
Jun 3, 2026
Merged

lkl: make object_is_on_stack() check host thread stacks#639
tavip merged 1 commit into
lkl:masterfrom
clingfei:master

Conversation

@clingfei

Copy link
Copy Markdown

blk_rq_map_kern() relies on object_is_on_stack() to route stack-allocated buffers to the bio_copy_kern() bounce path, since a buffer on the stack cannot be mapped directly into a bio.

object_is_on_stack() tests whether the buffer lies within [task_stack_page(current), task_stack_page(current) + THREAD_SIZE). On native architectures that range is the task's real execution stack, so the test works. Under LKL it does not: threads actually execute on host pthread stacks, and object_is_on_stack only checks whether it lies in init_thread_union.thread_info.stack. A buffer placed on the stack therefore lives on the host stack, outside the thread_info range, and object_is_on_stack() returns false. The bounce path is skipped and bio_map_kern() ends up calling virt_to_page() on a host-stack address that is not part of the kernel linear map, corrupting the I/O.

Add blk_kern_needs_copy() to detect this case by checking that both the start and the last byte of the buffer are virt_addr_valid(), and force the bio_copy_kern() bounce path when they are not. The check is guarded by CONFIG_LKL and compiles to false on other builds, so non-LKL kernels are unchanged.

@github-actions

github-actions Bot commented May 30, 2026

Copy link
Copy Markdown

Test Results

106 files  ±0  106 suites  ±0   7m 34s ⏱️ -10s
205 tests ±0  194 ✅ ±0  11 💤 ±0  0 ❌ ±0 
822 runs  ±0  766 ✅ ±0  56 💤 ±0  0 ❌ ±0 

Results for commit a2b0623. ± Comparison against base commit d25752c.

♻️ This comment has been updated with latest results.

@tavip tavip left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we instead have a custom object_is_on_stack for LKL by introducing something like _ARCH_HAS_OBJECT_IS_ON_STACK? After we added support for kasan we can now get the stack base and size, at least for posix hosts.

@clingfei

clingfei commented Jun 1, 2026

Copy link
Copy Markdown
Author

I actually considered this approach at first. However, after a brief look, I found that object_is_on_stack is used in many places throughout the kernel. Since LKL uses the host process's stack, the semantics of object_is_on_stack in this implementation may not be exactly the same as in the original Linux.

In the driver, all uses of this function are related to DMA, so I think they can be replaced directly. Do you think replacing object_is_on_stack in non-DMA areas (such as KASAN and tracing) would be safe, or might it introduce other issues? I am not very familiar with them.

@tavip

tavip commented Jun 3, 2026

Copy link
Copy Markdown
Member

I actually considered this approach at first. However, after a brief look, I found that object_is_on_stack is used in many places throughout the kernel. Since LKL uses the host process's stack, the semantics of object_is_on_stack in this implementation may not be exactly the same as in the original Linux.

I took a quick look and I've spotted of few places in USB and a couple other drivers that would benefit from it. We don't use USB yet, but there are some experimental projects using LKL that do (see the recent PRs) . For kasan it is currently a no-op because we don't enable KASAN_STACK. We don't use tracing yet, but even that seems to be a noop for LKL.

So overall I think it is safe and it would be a net benefit. If you have time working on this it would be great to get it implemented. If not I am ok with the change as it is for now.

@clingfei clingfei changed the title lkl: block: copy kernel buffers not in the linear map lkl: make object_is_on_stack() check host thread stacks Jun 3, 2026
@clingfei

clingfei commented Jun 3, 2026

Copy link
Copy Markdown
Author

I actually considered this approach at first. However, after a brief look, I found that object_is_on_stack is used in many places throughout the kernel. Since LKL uses the host process's stack, the semantics of object_is_on_stack in this implementation may not be exactly the same as in the original Linux.

I took a quick look and I've spotted of few places in USB and a couple other drivers that would benefit from it. We don't use USB yet, but there are some experimental projects using LKL that do (see the recent PRs) . For kasan it is currently a no-op because we don't enable KASAN_STACK. We don't use tracing yet, but even that seems to be a noop for LKL.

So overall I think it is safe and it would be a net benefit. If you have time working on this it would be great to get it implemented. If not I am ok with the change as it is for now.

Thanks for your reply! I have implemented it in the recent commit.

object_is_on_stack() assumes that task_stack_page(current) describes the
stack currently used for execution. That is not true for lkl: task->stack
contains the LKL thread_info allocation, while kernel code actually runs
on the host thread stack.

As a result, stack-allocated kernel buffers on LKL are not detected as
being on-stack. Callers such as blk_rq_map_kern() can then take the direct
mapping path and eventually call virt_to_page() on a host stack address,
which is not part of the kernel linear map.

Allow architectures to override the stack range check by providing
arch_object_is_on_stack() via __HAVE_ARCH_OBJECT_IS_ON_STACK, while keeping
the KASAN tag reset in the generic object_is_on_stack() helper.

Implement the LKL override using lkl_ops->thread_stack(), which returns the
current host thread stack base and size when the host provides it. This
lets all object_is_on_stack() callers handle LKL host-stack buffers
correctly, without adding a block-layer-specific workaround.

Signed-off-by: Cheng Lingfei <chenglingfei@foxmail.com>

@tavip tavip left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you @clingfei !

@tavip
tavip merged commit 9523b2a into lkl:master Jun 3, 2026
19 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants